package net.xfok.xmerge;

import net.xfok.rss.parser.Feed;
import net.xfok.rss.parser.Rss;
import net.xfok.xmerge.adapter.FeedAdapter;
import net.xfok.xmerge.adapter.RssAdapter;
import net.xfok.xmerge.manage.RssManage;
import net.xfok.xmerge.provider.RssItem;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

import com.mobclick.android.MobclickAgent;

public class RssList extends Activity implements OnItemClickListener,OnClickListener{
	private static final String TAG = "RssList";
	private static final String MIME_TYPE = "text/html";
	private static final String ENCODE = "utf-8";
	private static final int DIALOG_DELETE = 0;
	private static final int DIALOG_LOADING = 1;
	private static final int RSS_MODE=0;
	private static final int FEED_MODE=1;
	private static final int WEB_MODE=2;
	private ProgressDialog progress=null;
	private String name=null;
	private String title=null;
	private String summary=null;
	private String link=null;
	private int selected = (-1);
	private int feedPosition=0;
	private int feedLen=0;
	private final int MENU_ADD = Menu.FIRST;
	private final int MENU_IMPORT = Menu.FIRST+1;
	private RssAdapter rssAdapter = null;
	private FeedAdapter feedAdapter = null;
	private ListView rssList;
	private ListView feedList;
	private WebView feedView;
	private ViewGroup mContainer;
	private int mode;
	private Button btAdd,btImport,btNext,btPre,btBack;
	private Resources res;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mContainer=(ViewGroup)findViewById(R.id.container);
        rssList=(ListView)findViewById(R.id.rss_list);
        rssList.setOnItemClickListener(this);
        feedList=(ListView)findViewById(R.id.feed_list);
        feedList.setOnItemClickListener(this);
        btAdd=(Button)findViewById(R.id.bt_add);
        btAdd.setOnClickListener(this);
        btImport=(Button)findViewById(R.id.bt_import);
        btImport.setOnClickListener(this);
        btNext=(Button)findViewById(R.id.bt_next);
        btNext.setOnClickListener(this);
        btPre=(Button)findViewById(R.id.bt_pre);
        btPre.setOnClickListener(this);
        btBack=(Button)findViewById(R.id.bt_back);
        btBack.setOnClickListener(this);
        feedView = (WebView) this.findViewById(R.id.feed_view);
        res=getResources();
    }
    @Override
    public void onConfigurationChanged(Configuration config) {
        try {
            super.onConfigurationChanged(config);
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                
            }
        } catch (Exception ex) {
        }
    }
    
    public void onResume(){
		showRssList();
		super.onResume();
		MobclickAgent.onResume(this);
	}
    
    public void onPause(){
    	super.onPause();
    	MobclickAgent.onPause(this);
    }
    
    private void showRssList() { 
    	setTitle(res.getText(R.string.app_name));
        Uri rssUrl = RssItem.Rss.CONTENT_URI;
        Cursor cur = managedQuery(rssUrl, RssItem.Rss.COLUMNS, null, null, null );
        rssAdapter=new RssAdapter(this);
        if (cur.moveToFirst()) {
            do {
            	RssItem rssItem=RssManage.getRssItem(cur);
            	rssAdapter.add(rssItem);
            } while (cur.moveToNext());
        }else{
        	Toast.makeText(this,res.getText(R.string.alert_empty_rss), Toast.LENGTH_LONG).show();
        	importRss();
        }
        rssList.setAdapter(rssAdapter);
        rssList.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  	  
            public void onCreateContextMenu(ContextMenu menu, View v , ContextMenuInfo menuInfo){
        		getMenuInflater().inflate(R.menu.context, menu);
            }  
        });
    	btAdd.setVisibility(View.VISIBLE);
    	btImport.setVisibility(View.VISIBLE);
    	btNext.setVisibility(View.GONE);
    	btPre.setVisibility(View.GONE);
    	btBack.setVisibility(View.GONE);
        rssList.setVisibility(View.VISIBLE);
    	feedList.setVisibility(View.GONE);
    	feedView.setVisibility(View.GONE);
    	mode=RSS_MODE;
    }
    
    private void showFeedList(RssItem rssItem){   
    	if(RssManage.checkNet(this)){
	    	name=rssItem.getName();
			setTitle(rssItem.getName()+" - "+res.getText(R.string.app_name));
		    Rss parser=new Rss(rssItem.getUrl());
		    feedAdapter=new FeedAdapter(this);
		    for(Feed feedItem:parser.getFeeds()){
		    	feedAdapter.add(feedItem);
		    }
		    feedList.setAdapter(feedAdapter); 
	    	btAdd.setVisibility(View.GONE);
	    	btImport.setVisibility(View.GONE);
	    	btNext.setVisibility(View.GONE);
	    	btPre.setVisibility(View.GONE);
	    	btBack.setVisibility(View.VISIBLE);	
		    rssList.setVisibility(View.GONE);
		    feedView.setVisibility(View.GONE);
	    	feedList.setVisibility(View.VISIBLE);
	    	mode=FEED_MODE;
    	}
    }
    
    private void showFeed(Feed feed){ 	
    	if(RssManage.checkNet(this)){
	    	setFeed(feed);		
			feedView.getSettings().setJavaScriptEnabled(true);
			feedView.setWebViewClient(new FeedViewClient());
			feedView.loadDataWithBaseURL(link, getHtml(), MIME_TYPE, ENCODE, null);
	    	btAdd.setVisibility(View.GONE);
	    	btImport.setVisibility(View.GONE);
	    	btNext.setVisibility(View.VISIBLE);
	    	btPre.setVisibility(View.VISIBLE);
	    	btBack.setVisibility(View.VISIBLE);
			rssList.setVisibility(View.GONE);
			feedList.setVisibility(View.GONE);
		    feedView.setVisibility(View.VISIBLE);	
		    mode=WEB_MODE;
    	}
    }
    
    private void openRss(RssItem rssItem){  
    	try{
	    	showFeedList(rssItem);	    	
    	}catch(Exception e){
    		e.printStackTrace();
    		showRssList();
    	}
    }
    
    private void applyRotation(int position, float start, float end) {
        // Find the center of the container
        final float centerX = mContainer.getWidth() / 2.0f;
        final float centerY = mContainer.getHeight() / 2.0f;

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3dAnimation rotation =
                new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
        rotation.setDuration(500);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(new DisplayNextView(position));

        mContainer.startAnimation(rotation);
    }
    
    private final class SwapViews implements Runnable {
        private final int mPosition;

        public SwapViews(int position) {
            mPosition = position;
        }
        public void run() {
            final float centerX = mContainer.getWidth() / 2.0f;
            final float centerY = mContainer.getHeight() / 2.0f;
            Rotate3dAnimation rotation= new Rotate3dAnimation(90, 360, centerX, centerY, 310.0f, false);    
            switch (mode) {
				case RSS_MODE:
					if(mPosition>-1){
						RssItem rssItem=(RssItem)rssList.getAdapter().getItem(mPosition);
				        openRss(rssItem);
			        }else{
			        	importRss();
			        }
					break;
				case FEED_MODE:
					if(mPosition>-1){
						feedPosition=mPosition;
						feedLen=feedList.getAdapter().getCount();
						Feed feed=(Feed)feedList.getAdapter().getItem(mPosition);
						showFeed(feed);
			        }else{
			        	showRssList();
			        }
					break;
				case WEB_MODE:
					if(mPosition>-1){
						feedPosition=mPosition;
						feedLen=feedList.getAdapter().getCount();
						Feed feed=(Feed)feedList.getAdapter().getItem(mPosition);
						showFeed(feed);
					}else{
						mode=FEED_MODE;
				    	btAdd.setVisibility(View.GONE);
				    	btImport.setVisibility(View.GONE);
				    	btNext.setVisibility(View.GONE);
				    	btPre.setVisibility(View.GONE);
				    	btBack.setVisibility(View.VISIBLE);	
					    rssList.setVisibility(View.GONE);
					    feedView.setVisibility(View.GONE);
				    	feedList.setVisibility(View.VISIBLE);
					}
				default:
					break;
			}
            rotation.setDuration(1000);
            rotation.setFillAfter(true);
            rotation.setInterpolator(new DecelerateInterpolator());
            mContainer.startAnimation(rotation);
        }
    }
    
    
    private final class DisplayNextView implements Animation.AnimationListener {
        private final int mPosition;

        private DisplayNextView(int position) {
            mPosition = position;
        }

        public void onAnimationStart(Animation animation) {
        }

        public void onAnimationEnd(Animation animation) {
            mContainer.post(new SwapViews(mPosition));
        }

        public void onAnimationRepeat(Animation animation) {
        }
    }
    
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		// TODO Auto-generated method stub
		applyRotation(position, 0, 90);        
	}
	
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
			case R.id.bt_add:
				addRssUrl();
				break;
			case R.id.bt_import:
				applyRotation(-1, 0, 90);
				break;
			case R.id.bt_back:
				applyRotation(-1, 0, 90);
				break;
			case R.id.bt_next:
				if(feedPosition<(feedLen-1)){
					feedPosition++;
				}else{
					feedPosition=0;
				}
				applyRotation(feedPosition, 0, 90); 
				break;
			case R.id.bt_pre:
				if(feedPosition>0){
					feedPosition--;
				}else{
					feedPosition=feedLen-1;
				}
				applyRotation(feedPosition, 0, 90); 
				break;
			default:
				break;
		}
	}
	
	private void setFeed(Feed feed){
		title=feed.getTitle();
		summary=feed.getSummary();
		link=feed.getLink();
		setTitle(title+" - "+name);
	}
	
	private String getHtml(){
		StringBuilder html = new StringBuilder();
        html.append("<html><head><title>")
            .append(title)
            .append("</title>\n")
            .append(CSS)
            .append("</head><body>")
            .append(summary)
            .append("<p align=\"center\"><a target='_blank' href='")
            .append(link)
            .append("'>")
            .append(res.getText(R.string.link_original))
            .append("</a></p>")
//            .append("<p align=\"center\">")
//            .append(AD)
//            .append("</p>")
//            .append(STAT)
            .append("</body></html>");
        return html.toString();
	}
	private static final String AD;
	private static final String CSS;
	private static final String STAT;
	static {
        AD = new StringBuilder()
                .append("<script type=\"text/javascript\"><!--\n")
                .append("google_ad_client = \"pub-9614173710261984\";\n")
                .append("google_ad_slot = \"0427988313\";\n")
                .append("google_ad_width = 300;")
                .append("google_ad_height = 250;")
                .append("//-->\n")
                .append("</script>\n")
                .append("<script type=\"text/javascript\" ")
                .append("src=\"http://pagead2.googlesyndication.com/pagead/show_ads.js\"></script>")
                .toString();
        CSS = new StringBuilder()
                .append("<style type=\"text/css\">\n")
                .append("<!--\n")
                .append("a:link,a:visited { color:#09F; }\n")
                .append("a:active,a:hover { color:#F60; }\n")
                .append("-->\n")
                .append("</style>\n")
                .toString();
        STAT = new StringBuilder()
				.append("<div style=\"display:none\">")
				.append("<iframe height=\"0\" width=\"0\" src=\"http://www.xfok.net/xdict/xmerge.html\"></iframe>")		
				.append("</div>").toString();
    }
	final class FeedViewClient extends WebViewClient {
		@Override
		public boolean  shouldOverrideUrlLoading(WebView view, String url) {
			view.loadUrl(url);
			return false;
		}
		
		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			showDialog(DIALOG_LOADING);
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			if(progress!=null){
				progress.dismiss();
				progress=null;
			}
		}
	}
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, MENU_ADD, 0, res.getString(R.string.menu_add)).setIcon(android.R.drawable.ic_menu_add);
        menu.add(0, MENU_IMPORT, 0, res.getString(R.string.menu_import)).setIcon(android.R.drawable.ic_menu_more);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
	        case MENU_ADD:
	            addRssUrl();
	            break;
	    	case MENU_IMPORT:
		        applyRotation(-1, 0, 90);
		        break;
        }
        return true;
    }
    
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		switch (item.getItemId()) {
		case R.id.context_menu_item_open:
			applyRotation(info.position, 0, 90);
			return true;
		case R.id.context_menu_item_delete:
			selected=info.position;
			showDialog(DIALOG_DELETE);
			return true;
		}
		return super.onContextItemSelected(item);
	}
	
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_DELETE:
			return new AlertDialog.Builder(RssList.this).setIcon(
				android.R.drawable.ic_delete).setTitle(
				R.string.context_menu_item_delete_label).setMessage(
				R.string.alert_delete_rss).setPositiveButton(
				R.string.alert_dialog_ok,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog,
							int whichButton) {
						Log.i(TAG, "selected="+selected);
						RssItem rssItem=(RssItem)rssList.getAdapter().getItem(selected);
						RssManage.delRssItem(rssItem,RssList.this);
						showRssList();
					}
				}).setNegativeButton(R.string.alert_dialog_cancel,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog,
							int whichButton) {

						/* User clicked No so do some stuff */
					}
				}).create();
			case DIALOG_LOADING: {
				progress = new ProgressDialog(this);
				progress.setMessage(res.getText(R.string.dialog_message_loading));
				progress.setIndeterminate(true);
				progress.setCancelable(true);
				return progress;
			}
		}		
		return null;
	}
	
    private void addRssUrl() {
        final AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle(res.getText(R.string.dialog_title_add_rss));
        alert.setMessage(res.getText(R.string.dialog_message_add_rss));
        final EditText input = new EditText(this);
        input.setSingleLine();
        input.setText("http://");
        alert.setView(input);
        alert.setPositiveButton(
        		R.string.alert_dialog_ok,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        Log.i(TAG, input.getText().toString());
                        String url=input.getText().toString();                 
                        saveRss(url);
                    }
                }
        );
        alert.setNegativeButton(
        		R.string.alert_dialog_cancel,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    }
                }
        );
        alert.show();
    }
    
    private void importRss(){
    	Intent intent=new Intent(this, ImportList.class);
    	startActivity(intent);
    }
    
    private boolean saveRss(String url){
    	boolean result=true;
    	try{
    		Rss parser=new Rss(url);
    		String name=parser.getRssTitle();
    		Log.i(TAG,"name="+name);
    		if(name!=null&&!name.equals("")){
    			String charset=res.getText(R.string.rss_charset).toString();
    			RssItem rssItem=new RssItem(charset,name,url);
    			if(!rssIsExit(rssItem)){
    				RssManage.addRssItem(rssItem,this);
    			}
    			showRssList();
    		}else{
    			Toast.makeText(this,res.getText(R.string.dialog_message_error_url), Toast.LENGTH_LONG).show();
    			result=false;
    		}
    	}catch(Exception e){
    		e.printStackTrace();
    		Toast.makeText(this,res.getText(R.string.dialog_message_error_url), Toast.LENGTH_LONG).show();
    		result=false;
    	}
    	return result;
    }
    
    private boolean rssIsExit(RssItem rssItem){
		 boolean result=false;
		 Uri rssUrl = RssItem.Rss.CONTENT_URI;
		 String selection=RssItem.Rss.RSS_COLUMN_URL+" like '"+rssItem.getUrl()+"'";
	     Cursor cur = managedQuery(rssUrl, RssItem.Rss.COLUMNS , selection, null, null );
	     if(cur.getCount()>0){
	    	 result=true;
	     }
	     return result;
	 }

}